//: C20:Noisy.h
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 1999
// Copyright notice in Copyright.txt
// A class to track various object activities
#ifndef NOISY_H
#define NOISY_H
#include <iostream>

class Noisy
{
    static long create, assign, copycons, destroy;
    long id;
public:
    Noisy() : id(create++) {
        std::cout << "d[" << id << "]";
    }
    Noisy(const Noisy& rv) : id(rv.id) {
        std::cout << "c[" << id << "]";
        copycons++;
    }
    Noisy& operator=(const Noisy& rv) {
        std::cout << "(" << id << ")=[" <<
                  rv.id << "]";
        id = rv.id;
        assign++;
        return *this;
    }
    friend bool
    operator<(const Noisy& lv, const Noisy& rv) {
        return lv.id < rv.id;
    }
    friend bool
    operator==(const Noisy& lv, const Noisy& rv) {
        return lv.id == rv.id;
    }
    ~Noisy() {
        std::cout << "~[" << id << "]";
        destroy++;
    }
    friend std::ostream&
    operator<<(std::ostream& os, const Noisy& n) {
        return os << n.id;
    }
    friend class NoisyReport;
};

struct NoisyGen {
    Noisy operator()() {
        return Noisy();
    }
};

// A singleton. Will automatically report the
// statistics as the program terminates:
class NoisyReport
{
    static NoisyReport nr;
    NoisyReport() {} // Private constructor
public:
    ~NoisyReport() {
        std::cout << "\n-------------------\n"
                  << "Noisy creations: " << Noisy::create
                  << "\nCopy-Constructions: "
                  << Noisy::copycons
                  << "\nAssignments: " << Noisy::assign
                  << "\nDestructions: " << Noisy::destroy
                  << std::endl;
    }
};

// Because of these this file can only be used
// in simple test situations. Move them to a
// .cpp file for more complex programs:
long Noisy::create = 0, Noisy::assign = 0,
                                        Noisy::copycons = 0, Noisy::destroy = 0;
NoisyReport NoisyReport::nr;
#endif // NOISY_H ///:~
